#ifndef INNERNODE_H
#define INNERNODE_H

#include "BufferFrame.h"
#include "Node.h"

struct bla
{
    NodeHeader header;
    unsigned child0;
    long key0;
    unsigned child1;
    long key1;
    unsigned child2;
    long key2;
    unsigned child3;
    long key3;
    unsigned child4;
    long key4;
    unsigned child5;
};

struct SplitMergeResult
{
    bool splitted;
    char* newKey;

    SplitMergeResult() : splitted(false), newKey(NULL) {}
    ~SplitMergeResult() { delete[] newKey; }
};

class InnerNode
{
private:
    InnerNode(BufferFrame& page, NodeContext& nodeContext);
    BufferFrame& page;
    NodeContext& context;
    NodeHeader& header;

	unsigned getMaxEntryCount();
	char* dataStart();
	void swapNode(bool left, unsigned keepChildId, unsigned keepId);
	SplitMergeResult* mergeSplit(char* left, char* right, char* key);
	char* getNewKey(int position);

public:
    static InnerNode fromNew(BufferFrame& page, NodeContext& nodeContext);
    static InnerNode fromExisting(BufferFrame& page, NodeContext& nodeContext);

    bool hasEnoughSpaceForNewChild();

    SplitOp insert(char* key, TID tid);
    RemovalResult* remove(char* key, bool isRoot);
    TID lookup(char* key);
    index_iterator lookupRange(char* key1, char* key2);
    void visualize(IndexVisualizer& vis, unsigned pageId);
    void redirectNext(unsigned newNeighbour, bool lastOneDeleted);
};

#endif // INNERNODE_H_INCLUDED
